package com.liuzy.family.controller;

import java.util.Arrays;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.liuzy.family.config.Weixin;
import com.liuzy.family.util.StrKit;
import com.liuzy.family.weixin.SHA1;
import com.liuzy.family.weixin.WXBizMsgCrypt;
import com.liuzy.family.weixin.msg.InMsgParser;
import com.liuzy.family.weixin.msg.OutMsgXmlBuilder;
import com.liuzy.family.weixin.msg.in.InImageMsg;
import com.liuzy.family.weixin.msg.in.InLinkMsg;
import com.liuzy.family.weixin.msg.in.InLocationMsg;
import com.liuzy.family.weixin.msg.in.InMsg;
import com.liuzy.family.weixin.msg.in.InShortVideoMsg;
import com.liuzy.family.weixin.msg.in.InTextMsg;
import com.liuzy.family.weixin.msg.in.InVideoMsg;
import com.liuzy.family.weixin.msg.in.InVoiceMsg;
import com.liuzy.family.weixin.msg.in.event.InCustomEvent;
import com.liuzy.family.weixin.msg.in.event.InFollowEvent;
import com.liuzy.family.weixin.msg.in.event.InLocationEvent;
import com.liuzy.family.weixin.msg.in.event.InMassEvent;
import com.liuzy.family.weixin.msg.in.event.InMenuEvent;
import com.liuzy.family.weixin.msg.in.event.InQrCodeEvent;
import com.liuzy.family.weixin.msg.in.event.InShakearoundUserShakeEvent;
import com.liuzy.family.weixin.msg.in.event.InTemplateMsgEvent;
import com.liuzy.family.weixin.msg.in.event.InVerifyFailEvent;
import com.liuzy.family.weixin.msg.in.event.InVerifySuccessEvent;
import com.liuzy.family.weixin.msg.in.speech_recognition.InSpeechRecognitionResults;
import com.liuzy.family.weixin.msg.out.OutCustomMsg;
import com.liuzy.family.weixin.msg.out.OutMsg;
import com.liuzy.family.weixin.msg.out.OutTextMsg;

/**
 * @author liuzy 2016年2月22日下午4:17:48
 */
@Controller
public class WeixinController extends BaseController {
	String signature;
	String timestamp;
	String nonce;
	String echostr;
	String encrypt_type;
	String msg_signature;
	String xmlData;
	InMsg inMsg;
	HttpServletRequest request;
	HttpServletResponse response;

	@RequestMapping("/wx")
	public void wx(String signature, String timestamp, String nonce, String echostr, String encrypt_type, String msg_signature, HttpServletRequest request, HttpServletResponse response) {
		this.signature = signature;
		this.timestamp = timestamp;
		this.nonce = nonce;
		this.echostr = echostr;
		this.encrypt_type = encrypt_type;
		this.msg_signature = msg_signature;
		this.xmlData = getXmlData(request);
		if (!StrKit.isBlank(xmlData)) {
			this.xmlData = new WXBizMsgCrypt(Weixin.token, Weixin.encodingAesKey, Weixin.appId).decryptMsg(msg_signature, timestamp, nonce, xmlData);
			System.out.println("-------------- in -----------------");
			System.out.println(xmlData);
			this.inMsg = InMsgParser.parse(xmlData);
		}
		this.request = request;
		this.response = response;
		if (!StrKit.isBlank(echostr))
			token();
		else if (inMsg instanceof InTextMsg)
			inTextMsg((InTextMsg) inMsg);
		else if (inMsg instanceof InImageMsg)
			inImageMsg((InImageMsg) inMsg);
		else if (inMsg instanceof InVoiceMsg)
			inVoiceMsg((InVoiceMsg) inMsg);
		else if (inMsg instanceof InVideoMsg)
			inVideoMsg((InVideoMsg) inMsg);
		else if (inMsg instanceof InShortVideoMsg)   //支持小视频
			inShortVideoMsg((InShortVideoMsg) inMsg);
		else if (inMsg instanceof InLocationMsg)
			inLocationMsg((InLocationMsg) inMsg);
		else if (inMsg instanceof InLinkMsg)
			inLinkMsg((InLinkMsg) inMsg);
        else if (inMsg instanceof InCustomEvent)
            inCustomEvent((InCustomEvent) inMsg);
		else if (inMsg instanceof InFollowEvent)
			inFollowEvent((InFollowEvent) inMsg);
		else if (inMsg instanceof InQrCodeEvent)
			inQrCodeEvent((InQrCodeEvent) inMsg);
		else if (inMsg instanceof InLocationEvent)
			inLocationEvent((InLocationEvent) inMsg);
        else if (inMsg instanceof InMassEvent)
            inMassEvent((InMassEvent) inMsg);
		else if (inMsg instanceof InMenuEvent)
			inMenuEvent((InMenuEvent) inMsg);
		else if (inMsg instanceof InSpeechRecognitionResults)
			inSpeechRecognitionResults((InSpeechRecognitionResults) inMsg);
		else if (inMsg instanceof InTemplateMsgEvent)
			inTemplateMsgEvent((InTemplateMsgEvent)inMsg);
		else if (inMsg instanceof InShakearoundUserShakeEvent)
			inShakearoundUserShakeEvent((InShakearoundUserShakeEvent)inMsg);
		else
			System.out.println("未能识别的消息类型。 消息 xml 内容为：\n" + inMsg);
	}
	public void token() {
		String[] arr = { Weixin.token, timestamp, nonce };
		Arrays.sort(arr);
		String str = arr[0] + arr[1] + arr[2];
		if (signature != null && signature.equals(SHA1.getSHA1(str))) {
			render(echostr);
		}
	}
	public void inTextMsg(InTextMsg inTextMsg) {
		switch (inTextMsg.getContent()) {
		case "生日":
			
			break;
		case "美女":
			
			break;
		default:
			break;
		}
		OutTextMsg text = new OutTextMsg();
		text.setToUserName(inTextMsg.getFromUserName());
		text.setCreateTime(new Long(new Date().getTime()).intValue());
		text.setFromUserName(inTextMsg.getToUserName());
		text.setContent("https://family.liuzy.xyz/");
		render(text);
	}

	
	public void inVoiceMsg(InVoiceMsg inVoiceMsg) {
		OutCustomMsg outCustomMsg = new OutCustomMsg(inVoiceMsg);
		render(outCustomMsg);
	}

	
	public void inVideoMsg(InVideoMsg inVideoMsg) {
		OutCustomMsg outCustomMsg = new OutCustomMsg(inVideoMsg);
		render(outCustomMsg);
	}

	
	public void inShortVideoMsg(InShortVideoMsg inShortVideoMsg) {
		OutCustomMsg outCustomMsg = new OutCustomMsg(inShortVideoMsg);
		render(outCustomMsg);
	}

	
	public void inLocationMsg(InLocationMsg inLocationMsg) {
		OutCustomMsg outCustomMsg = new OutCustomMsg(inLocationMsg);
		render(outCustomMsg);
	}

	
	public void inLinkMsg(InLinkMsg inLinkMsg) {
		OutCustomMsg outCustomMsg = new OutCustomMsg(inLinkMsg);
		render(outCustomMsg);
	}

	
	public void inCustomEvent(InCustomEvent inCustomEvent) {
		System.out.println("测试方法：inCustomEvent()");
	}

	public void inImageMsg(InImageMsg inImageMsg) {
		OutCustomMsg outCustomMsg = new OutCustomMsg(inImageMsg);
		render(outCustomMsg);
	}

	public void inFollowEvent(InFollowEvent inFollowEvent) {
		if (InFollowEvent.EVENT_INFOLLOW_SUBSCRIBE.equals(inFollowEvent.getEvent())) {
			System.out.println("关注：" + inFollowEvent.getFromUserName());
			OutTextMsg outMsg = new OutTextMsg(inFollowEvent);
			outMsg.setContent("这是Jfinal-weixin测试服务</br>\r\n感谢您的关注");
			render(outMsg);
		}
		// 如果为取消关注事件，将无法接收到传回的信息
		if (InFollowEvent.EVENT_INFOLLOW_UNSUBSCRIBE.equals(inFollowEvent.getEvent())) {
			System.out.println("取消关注：" + inFollowEvent.getFromUserName());
		}
	}

	
	public void inQrCodeEvent(InQrCodeEvent inQrCodeEvent) {
		if (InQrCodeEvent.EVENT_INQRCODE_SUBSCRIBE.equals(inQrCodeEvent.getEvent())) {
			System.out.println("扫码未关注：" + inQrCodeEvent.getFromUserName());
			OutTextMsg outMsg = new OutTextMsg(inQrCodeEvent);
			outMsg.setContent("感谢您的关注，二维码内容：" + inQrCodeEvent.getEventKey());
			render(outMsg);
		}
		if (InQrCodeEvent.EVENT_INQRCODE_SCAN.equals(inQrCodeEvent.getEvent())) {
			System.out.println("扫码已关注：" + inQrCodeEvent.getFromUserName());
		}
	}

	
	public void inLocationEvent(InLocationEvent inLocationEvent) {
		System.out.println("发送地理位置事件：" + inLocationEvent.getFromUserName());
		OutTextMsg outMsg = new OutTextMsg(inLocationEvent);
		outMsg.setContent("地理位置是：" + inLocationEvent.getLatitude());
		render(outMsg);
	}

	
	public void inMassEvent(InMassEvent inMassEvent) {
		System.out.println("测试方法：inMassEvent()");
	}

	/**
	 * 实现父类抽方法，处理自定义菜单事件
	 */
	public void inMenuEvent(InMenuEvent inMenuEvent) {
		System.out.println("菜单事件：" + inMenuEvent.getFromUserName());
		OutTextMsg outMsg = new OutTextMsg(inMenuEvent);
		outMsg.setContent("菜单事件内容是：" + inMenuEvent.getEventKey());
		render(outMsg);
	}

	
	public void inSpeechRecognitionResults(InSpeechRecognitionResults inSpeechRecognitionResults) {
		System.out.println("语音识别事件：" + inSpeechRecognitionResults.getFromUserName());
		OutTextMsg outMsg = new OutTextMsg(inSpeechRecognitionResults);
		outMsg.setContent("语音识别内容是：" + inSpeechRecognitionResults.getRecognition());
		render(outMsg);
	}

	
	public void inTemplateMsgEvent(InTemplateMsgEvent inTemplateMsgEvent) {
		System.out.println("测试方法：inTemplateMsgEvent()");
	}

	
	public void inShakearoundUserShakeEvent(InShakearoundUserShakeEvent inShakearoundUserShakeEvent) {
		System.out.println("摇一摇周边设备信息通知事件：" + inShakearoundUserShakeEvent.getFromUserName());
		OutTextMsg outMsg = new OutTextMsg(inShakearoundUserShakeEvent);
		outMsg.setContent("摇一摇周边设备信息通知事件UUID：" + inShakearoundUserShakeEvent.getUuid());
		render(outMsg);
	}

	
	public void inVerifySuccessEvent(InVerifySuccessEvent inVerifySuccessEvent) {
		System.out.println("资质认证成功通知事件：" + inVerifySuccessEvent.getFromUserName());
		OutTextMsg outMsg = new OutTextMsg(inVerifySuccessEvent);
		outMsg.setContent("资质认证成功通知事件：" + inVerifySuccessEvent.getExpiredTime());
		render(outMsg);
	}

	
	public void inVerifyFailEvent(InVerifyFailEvent inVerifyFailEvent){
		System.out.println("资质认证失败通知事件：" + inVerifyFailEvent.getFromUserName());
		OutTextMsg outMsg = new OutTextMsg(inVerifyFailEvent);
		outMsg.setContent("资质认证失败通知事件：" + inVerifyFailEvent.getFailReason());
		render(outMsg);
	}

	private void render(String msg) {
		try {
			response.getWriter().print(msg);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void render(OutMsg msg) {
		try {
			String outMsgXml = OutMsgXmlBuilder.build(msg);
			WXBizMsgCrypt bizMsgCrypt = new WXBizMsgCrypt(Weixin.token, Weixin.encodingAesKey, Weixin.appId);
			outMsgXml = bizMsgCrypt.encryptMsg(outMsgXml, timestamp, nonce);
			System.out.println("-------------- out ----------------");
			System.out.println(outMsgXml);
			response.getWriter().print(outMsgXml);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
